// 反恐玩法 插件

//--------------------------------------------全局变量----------------------------------------
string author = "Live";
string pluginName = "CS 反恐玩法插件";
string version = "1.0";

// 无限备弹？
bool test_infiniteCollectedAmmo = true;
// 无限体力？
bool test_infiniteStamina = true;
// 是否开启无限刷
bool MAX_spawn = true;
// 玩家列表
array<int> playerList;
// 默认想刷的土匪常量
int NPCC = 10;
// 土匪常量是否根据人数决定
bool playerToNPCC = true;
// 自动设置常量的倍数（默认10/人）
int NPCCMF = 10;
// 设置僵尸生成点多近会开刷(单位：米)
int distance_respawn = 10;
// 设置土匪有多远被删除
int distance_delete = 15;

// 预缓存特警模型列表
const array<string> s_PlayerModels = {
"models/survivors/male/riot_officer.mdl"
};

// 预缓存特警手臂模型列表
const array<string> s_PlayerArmModels = {
"models/weapons/v_shared/v_hands_ryan.mdl"
};

//--------------------------------------------插件初始化----------------------------------------

// 插件初始化
void OnPluginInit()
{
    // 设置插件信息
    PluginData::SetAuthor(author);
    PluginData::SetName(pluginName);
    PluginData::SetVersion(version);

    // 加载后提示信息
    ThePresident.InfoFeed("插件:"+pluginName+"| 版本:"+version+"| 作者:"+author,false);

    // 当僵尸出生后
    Events::Infected::OnInfectedSpawned.Hook( @OnInfectedSpawned );
    // 当玩家说
    Events::Player::PlayerSay.Hook( @PlayerSay );
    // NPC被杀
    Events::Survivor::OnSurvivorKilled.Hook( @OnSurvivorKilled );
    // 当回合终止时
    Events::ThePresident::OnTerminateRound.Hook( @OnTerminateRound );
    // 实体掉落
    Events::Player::OnEntityDropped.Hook( @OnEntityDropped );
    // 当玩家出生时
    Events::Player::OnPlayerSpawn.Hook( @OnPlayerSpawn );
    // 当幸存者将要被伤害时
    //Events::Survivor::OnSurvivorDamagedPre.Hook( @OnSurvivorDamagedPre );
    // 玩家执行菜单
    Events::Player::OnMenuExecuted.Hook( @OnMenuExecuted );
    // 当玩家连接后
    Events::Player::OnPlayerConnected.Hook( @OnPlayerConnected );
    // 当玩家断开连接时
    Events::Player::OnPlayerDisconnected.Hook( @OnPlayerDisconnected );
    // 当玩家被杀死后
    Events::Player::OnPlayerKilledPost.Hook( @OnPlayerKilledPost );
    // 当玩家受到伤害后
    Events::Player::OnPlayerDamaged.Hook( @OnPlayerDamaged );

    // 地图开始 
    ThePresident_OnMapStart();

}

//--------------------------------------------回合控制----------------------------------------

// 地图开始
void ThePresident_OnMapStart()
{
    // 缓存所有角色模型
    for( uint i = 0; i < s_PlayerModels.length(); i++ ){
        Engine.PrecacheFile( model, s_PlayerModels[i] );
    }

    // 缓存所有手臂模型
    for( uint i = 0; i < s_PlayerModels.length(); i++ ){
        Engine.PrecacheFile( model, s_PlayerArmModels[i] );
    }

    // 回合开始
    ThePresident_OnRoundStart();
}

// 回合开始
void ThePresident_OnRoundStart()
{
	// 服务器中文名
    Engine.RunConsoleCommand( "hostname [CN.Live] 娱乐 | 反恐服（无持枪） CS QQ群392635015");
    // 设置难度
    Engine.RunConsoleCommand( "Difficulty 4");
    // 设置无法投票更改难度
    Engine.RunConsoleCommand( "sv_vote_issue_change_difficulty_allowed 0" );
	// 仅AI丧尸（玩家死亡不会变丧尸）
    Engine.RunConsoleCommand( "cg_zombie_ai_only 1" );
    // 无感染
    Engine.RunConsoleCommand( "cg_infection_disabled 1" );
    // 拒绝僵尸生成
    //Engine.RunConsoleCommand( "thepresident_refuse_zombiespawn 1" );
    // 僵尸最大值
    //ThePresident.MaxZombiesAllowed(10);
	
    // 检查是否开启无限体力
    infiniteStamina();

    // 检查是否开启无限子弹
    sv_infinite_collected_ammo();

    // 设置僵尸常数为0
    ThePresident.SetSpawnZombiesConstant(0);

    // 调用无限刷方法
    MAXZOMBIE();

    // 调用远距离检测删除方法
    deleteNPC();

    //设置玩家初始武器
    //手雷、mpk5、雷明顿
    ThePresident.AddSpawnWeaponOverride(1, "grenade", 0, 0);
    ThePresident.AddSpawnWeaponOverride(2, "mp5k", 150, 150);
    ThePresident.AddSpawnWeaponOverride(3, "remington870", 24, 24);

    // 快速切换
    ThePresident.OverrideWeaponFastSwitch(true);

}

// 无限体力
void infiniteStamina(){
    // 如果无限体力开启，执行一次（防止因为防卫模式把无限体力关了）
    if(test_infiniteStamina){
        CASConVarRef@ infiniteStamina= ConVar::Find( "sv_infinite_stamina" );
        infiniteStamina.SetValue("1");
        Chat.PrintToChat(all,"{hotpink}已自动开启无限体力");
    }
}

// 无限子弹
void sv_infinite_collected_ammo(){
    // 如果无限子弹开启，执行
    CASConVarRef@ infiniteStamina= ConVar::Find( "sv_infinite_collected_ammo" );
    if(test_infiniteCollectedAmmo){
        infiniteStamina.SetValue("1");
        Chat.PrintToChat(all,"{hotpink}已自动开启无限子弹");
        // 因为无法区别钉枪木板（也属于子弹），防止删除木板资源，故不再清除地图子弹
        //removeAllAmmo();
        //Chat.PrintToChat(all,"{hotpink}已清除地图所有子弹");
    }else{
        infiniteStamina.SetValue("0");
        Chat.PrintToChat(all,"{hotpink}已自动关闭无限子弹");
    }
}

// 回合终止时
HookReturnCode OnTerminateRound(int iTeam)
{
    return HOOK_CONTINUE;
}
/*******************************************************************************************

                                                HOOK

********************************************************************************************/

//--------------------------------------------玩家连接----------------------------------------

// 当玩家连接后
HookReturnCode OnPlayerConnected(CTerrorPlayer@ pPlayer)
{
    setNPCC();
    Chat.PrintToChat(pPlayer,"复活(respawn){gold}!fh{white}、医疗包(firstaid){gold}!f");
    return HOOK_CONTINUE;
}

//--------------------------------------------玩家断开----------------------------------------

// 当玩家断开连接后
HookReturnCode OnPlayerDisconnected(CTerrorPlayer@ pPlayer)
{
    setNPCC();
    return HOOK_CONTINUE;
}

// 设置更新NPCC
void setNPCC(){
	int maxNUM = 60;
    if( playerToNPCC ){
        int playerNum = Utils.CollectPlayers().length();
        if( playerNum * NPCCMF < maxNUM)
            NPCC = playerNum * NPCCMF;
        else
            NPCC = maxNUM;
        Chat.PrintToChat(all,"当前玩家人数为：{gold}"+playerNum+"{white}、常量为{gold}"+NPCC+"{white},每增加一人，增加"+NPCCMF+"个，最多"+maxNUM);
    }
}

//--------------------------------------------玩家出生----------------------------------------
// 玩家出生
HookReturnCode OnPlayerSpawn(CTerrorPlayer@ pPlayer)
{
    if( pPlayer.GetTeamNumber() == TEAM_SURVIVOR ){
        // 设置特警皮肤
        Schedule::Task( 2.0, pPlayer.entindex(), ChangeSkin );
    }
    return HOOK_CONTINUE;
}

void ChangeSkin(int index){ 
	FindEntityByEntIndex(index).SetModel( s_PlayerModels[ Math::RandomInt( 0, s_PlayerModels.length() - 1 ) ] );
	CTerrorPlayer@ pPlayer = ToTerrorPlayer(index);
	pPlayer.SetArmModel( s_PlayerArmModels[ Math::RandomInt( 0, s_PlayerArmModels.length() - 1 ) ] );
}

//--------------------------------------------玩家死亡----------------------------------------

//当玩家死亡后
HookReturnCode OnPlayerKilledPost(CTerrorPlayer@ pPlayer)
{
    // 杀戮提示信息
    ThePresident.FakeKillFeed("黑帮牢大", pPlayer.GetPlayerName(), "weapon_remington870", true, TEAM_ZOMBIE, TEAM_SURVIVOR);
	Open_PlayerShop_Tele(pPlayer);
    return HOOK_CONTINUE;
}

//--------------------------------------------玩家掉落----------------------------------------
// 玩家实体掉落
HookReturnCode OnEntityDropped(CTerrorPlayer@ pPlayer, CBaseEntity@ pEntity)
{
    if(pEntity.ClassnameIs("item_ammo_*")){
        pEntity.SUB_Remove();
    }
	return HOOK_CONTINUE;
}

//--------------------------------------------玩家受伤(呼吸回血)----------------------------------------

HookReturnCode OnPlayerDamaged(CTerrorPlayer@ pPlayer, CTakeDamageInfo &in DamageInfo)
{
    Schedule::Task( 8.0f,pPlayer.entindex(),addHealth );
	return HOOK_CONTINUE;
}

// 呼吸回血
void addHealth(int index){
    CTerrorPlayer@ pPlayer = ToTerrorPlayer(index);
    if( pPlayer.GetHealth() < pPlayer.GetMaxHealth() && pPlayer.GetTeamNumber() == TEAM_SURVIVOR ){
        pPlayer.SetHealth( pPlayer.GetHealth() + 2 );
        Schedule::Task( 1.0f, index, addHealth );
    }
}

//--------------------------------------------僵尸（土匪）生成----------------------------------------
//僵尸出生后
HookReturnCode OnInfectedSpawned(Infected@ pInfected)   
{

    // 获取所生成的僵尸位置
    Vector zombieV = pInfected.GetAbsOrigin();

    // 删除该僵尸
    pInfected.SUB_Remove();

    /* ----------------然后用这个僵尸的坐标来刷我们的土匪---------- */

    int num = Utils.CollectSurvivors().length();
    // 防止意外情况发生实体爆炸
    if( num < 150 && num < NPCC){

        // 创建实体数据
        CEntityData@ inputdata = EntityCreator::EntityData();
        // 从1到10中拿取一个随机数
        //int RandomInt1 = Math::RandomInt(1,10);
        // 如果随机数<5，也就是说，4/10的概率
        //if( RandomInt1 < 5 ){
            // 4/10的概率设置土匪武器为拳头
            inputdata.Add( "weapons", "-1" );
        // }else{
            // // 6/10的概率设置土匪使用武器
            // // 而这6/10的土匪又随机从1-10种武器中随机拿枪
            // int RandomInt2 = Math::RandomInt(1,10);
            // inputdata.Add( "weapons", ""+RandomInt2 );
        // }

        // 最后，创建我们的土匪实体(zombieV.z是让其眼光在同一水平，而不是朝天)
        CBaseEntity@ CNPC = EntityCreator::Create("psycho", zombieV , QAngle(0,0,0), inputdata);

        // 设置其实体名，方便区分
        CNPC.SetEntityName("npc");

        Log.PrintToServerConsole(LOGTYPE_INFO,"----------now---------"+num);

        // 修改其武器的实体名（因为没有幸存者武器的掉落Hook，这里改名处理方便删除掉落）
        //updateWeaponName();

    }

    return HOOK_CONTINUE;
}

// 修改武器实体名（不要修改类名，实测如果类名变化，会无法拾取）
void updateWeaponName(){
    string name = "weapon_*";
    // 查找类名，所有武器
    CBaseEntity @pEnt = FindEntityByClassname(null,name);
    while( pEnt !is null ){
        // 获取其拥有者
        CBaseEntity@ base = pEnt.GetOwner();
        // 如果这把枪有人在使用并且是我们刷的npc，就改实体名
        if( base !is null && base.GetEntityName() == "npc"){
            pEnt.SetEntityName("npc_weapon");
        }
        @pEnt = FindEntityByClassname(pEnt,name);
    }
}

//--------------------------------------------当NPC被杀时----------------------------------------
// NPC被杀
HookReturnCode OnSurvivorKilled(Survivor@ pSurvivor, CTakeDamageInfo &in DamageInfo)
{
    // 清子弹
    //Schedule::Task( 0,cleanAmmo );
    // 清除武器
    //deleteWeapon();
	return HOOK_HANDLED;
}

void cleanAmmo(){
    // 清除所有子弹
    string ammo = "item_ammo_*";
    CBaseEntity @pEnt = FindEntityByClassname( null, ammo );
    while( pEnt !is null)
    {
        if( pEnt.GetEntityName() != "item_ammo_barricade" ){
            pEnt.SetClassname("delete_ammo");
            pEnt.SUB_StartFadeOut(1,false);
        }
        else{
            pEnt.SetClassname("barricade");
        }
        @pEnt = FindEntityByClassname( pEnt, ammo );
    }
}

void deleteWeapon(){
    string name = "npc_weapon";
    CBaseEntity @base = FindEntityByName( null, name );
    while( base !is null ){
        if( base.GetOwner() is null ){
            // 根据实测，如果不改名，下次又会找到这个枪并重新30秒，所以先改个名
            base.SetEntityName("drop_weapon");
            base.SUB_StartFadeOut(30.0f,false);
        }
        @base = FindEntityByName( base, name );
    }
}

//--------------------------------------------当NPC即将受到伤害时----------------------------------------

HookReturnCode OnSurvivorDamagedPre(Survivor@ pSurvivor, CTakeDamageInfo &in DamageInfo)
{
    CBaseEntity@ pAttacker = DamageInfo.GetAttacker();	//获取攻击者信息
    if( pAttacker.GetClassname() != "player" ){
        DamageInfo.SetDamage(0);
    }
	return HOOK_CONTINUE;
}

/*******************************************************************************************

                                                玩家命令

********************************************************************************************/

HookReturnCode PlayerSay(CTerrorPlayer@ pPlayer, CASCommand@ pArgs){

    // ---------------------字符串切分处理------------------------

    string arg = pArgs.Arg( 1 );
	string arg1 = "";
	string arg2 = "";

	// 切分字符串(这样就可以用空格传一个命令参数了)
	int subIndex = arg.findFirst(" ",0);
	if(not (subIndex < 0)){
		arg1 = arg.substr(0,subIndex);
		arg2 = arg.substr(subIndex+1,-1);
		//Chat.PrintToChat(all,""+arg1+"|"+arg2);
	}else{
		arg1 = arg;
	}

    //-----------------------玩家命令------------------------------

    if( AdminSystem.AdminExist(pPlayer) ){
        if(arg1=="!tili"){
            CASConVarRef@ infiniteStamina= ConVar::Find( "sv_infinite_stamina" );
            if( test_infiniteStamina ){
                infiniteStamina.SetValue("0");
                Chat.PrintToChat( all,"{hotpink}无限体力关闭" );
            }else{
                infiniteStamina.SetValue("1");
                Chat.PrintToChat( all,"{hotpink}无限体力开启" );
            }
            test_infiniteStamina = ! test_infiniteStamina;
        }else if(arg1 == "!ammo"){
            CASConVarRef@ sv_infinite_collected_ammo = ConVar::Find( "sv_infinite_collected_ammo" );
            if( test_infiniteCollectedAmmo ){
                sv_infinite_collected_ammo.SetValue("0");
                Chat.PrintToChat(pPlayer,"{hotpink}无限备弹关闭");
            }else{
                sv_infinite_collected_ammo.SetValue("1");
                Chat.PrintToChat(pPlayer,"{hotpink}无限备弹开启");
                //removeAllAmmo();
                //Chat.PrintToChat(all,"{hotpink}已清除地图所有子弹");
            }
            test_infiniteCollectedAmmo = ! test_infiniteCollectedAmmo;
        }else if(arg1 == "!sel"){
            Chat.PrintToChat(all,"幸存者数组查询："+Utils.CollectSurvivors().length());
        }else if(arg1 == "!give"){
            if( arg2!="" ){
                pPlayer.GiveWeapon(arg2);
            }
        }else if(arg1 == "!dev"){
			Engine.RunConsoleCommand("sv_cheats 1");
			Engine.RunConsoleCommand("developer 1");
			Engine.RunConsoleCommand("god 1");
		}else if( arg1 == "!nc" ){
            if( arg2 != "" ){
                NPCC = Utils.StringToInt(arg2);
                Chat.PrintToChat(pPlayer,"成功设置NPC常量为{hotpink}"+NPCC);
            }
        }else if( arg1 == "!zd" ){
            if(playerToNPCC){
                playerToNPCC = false;
                Chat.PrintToChat(pPlayer,"自动设置常量关闭");
            }else{
                playerToNPCC = true;
                Chat.PrintToChat(pPlayer,"自动设置常开启");
            }
        }else if( arg1 == "!mf" ){
            if( arg2!="" ){
                NPCCMF = Utils.StringToInt(arg2);
                Chat.PrintToChat(pPlayer,"设置每人"+arg2+"个成功！");
                setNPCC();
            }
        }else if( arg1 == "!dr" ){
            if( arg2!="" ){
                distance_respawn = Utils.StringToInt(arg2);
                Chat.PrintToChat(all,"设置最远生成距离为{gold}"+arg2+"米");
            }
        }else if( arg1 == "!dd" ){
            if( arg2!="" ){
                distance_delete = Utils.StringToInt(arg2);
                Chat.PrintToChat(all,"设置最近删除距离为{gold}"+arg2+"米");
            }
        }
    }
    if( arg1 == "!fh" ){
        Open_PlayerShop_Tele(pPlayer);
    }else if(arg1 == "!k"){
        Engine.RunConsoleCommand( "admin slay !" + pPlayer.entindex() );
    }else if( arg1 == "!f" ){
		pPlayer.GiveWeapon("firstaid");
	}
    return HOOK_CONTINUE;
}

/*******************************************************************************************

                                                菜单

********************************************************************************************/

//--------------------------------------------菜单内容----------------------------------------

// 打开玩家传送菜单（index从0开始）
void Open_PlayerShop_Tele(CTerrorPlayer@ pPlayer){
    Menu_PlayerShop_Tele(pPlayer,0);
}

// 玩家传送菜单
void Menu_PlayerShop_Tele(CTerrorPlayer@ pPlayer,int index){
    if (pPlayer is null ) return;
    playerList = Utils.CollectPlayers();
    Menu pMenu;
	pMenu.SetID( "Menu_PlayerShop_Tele_Select;"+index );
	pMenu.SetTitle( "@请选择复活到谁@" );
    // 内容填充方法（填充玩家）
    Player_ItemFill(pPlayer,pMenu,index);
}

// 内容填充方法，从index开始
void Player_ItemFill(CTerrorPlayer@ pPlayer,Menu pMenu,int index){
    // 计数
    int count = 0;
    for(uint i=index;i<playerList.length();i++){
        CBasePlayer@ player = ToBasePlayer(playerList[i]);
        pMenu.AddItem(""+player.GetPlayerName());
        // 因为菜单一页只能有七个
        if(count>6) break;
        count++;
    }
    pMenu.SetBack( true );
    // 如果大于7项，就有下一页按钮
    if(count>6){
        pMenu.SetNext( true );
    }
    pMenu.Display( pPlayer, -1 );
}

//--------------------------------------------菜单执行----------------------------------------

HookReturnCode OnMenuExecuted(CTerrorPlayer@ pPlayer, const string &in szID, int &in iValue)
{
    // 复活
    if( Utils.StrContains("Menu_PlayerShop_Tele_Select", szID)){
        // 得到下标
        CASCommand@ arg = StringToArgSplit(szID, ";");
        int index =  Utils.StringToInt(arg.Arg(1));
        if(iValue == 8){
            // 如果是0则第一页，返回就是返回玩家商店
            if( index != 0 )
                Menu_PlayerShop_Tele(pPlayer,index-7);
        }else if(iValue == 9){
            Menu_PlayerShop_Tele(pPlayer,index+7);
        }else if(iValue>0 && iValue<8){
            iValue = iValue + index;
            if( pPlayer.GetTeamNumber() != TEAM_SURVIVOR ){
                int pPlayerIndex = playerList[iValue-1];
                if(pPlayerIndex == pPlayer.entindex()){
                    Chat.PrintToChat(pPlayer,"{hotpink}请选择除自己之外的人");
                }else{
					CBasePlayer@ telePlayer = ToBasePlayer(pPlayerIndex);
					// 判断所选择的玩家是否是人类
					if(telePlayer.GetTeamNumber() == TEAM_SURVIVOR){
						// 修改被复活玩家的游戏阵营
						pPlayer.ChangeTeam( TEAM_SURVIVOR );
						// 复活玩家
						pPlayer.Respawn();
						// 得到被选择玩家的位置
						Vector teleV = telePlayer.GetAbsOrigin();
						// 将复活玩家传送过去
						pPlayer.SetAbsOrigin(teleV);
						Chat.PrintToChat(all,"{hotpink}"+pPlayer.GetPlayerName()+"复活了自己到"+telePlayer.GetPlayerName());
					}else{
						Chat.PrintToChat(pPlayer,"{hotponk}请选择一个人类");
					}
                }
            }else{
                Chat.PrintToChat(pPlayer,"{hotpink}人死才能复生");
            }
        }
    }
    return HOOK_CONTINUE;
}

/*******************************************************************************************

                                                其它方法

********************************************************************************************/

//--------------------------------------------删除NPC----------------------------------------

// 删除距离玩家非常远的NPC，防止摸鱼充数卡顿
void deleteNPC(){

    // 每10秒检测一次
    Schedule::Task( 10.0f , deleteNPC );
    Log.PrintToServerConsole(LOGTYPE_INFO,"-------------check Delete--------------");

    array<int> npc = Utils.CollectSurvivors();
    playerList = Utils.CollectPlayers();
    bool needDelete;
    
    // 遍历这个土匪
    for( uint i=0;i<npc.length();i++ ){

        // 默认需要删除，只要有人在其100内就不删除
        needDelete = true;
        CBaseEntity@ base = FindEntityByEntIndex(npc[i]);

        if( base.GetClassname() == "psycho" ){

            // 遍历玩家，看这个土匪是不是距离所有玩家都超过了100米
            for(uint j=0;j<playerList.length();j++){

               CTerrorPlayer@ pPlayer = ToTerrorPlayer(playerList[j]);

               if( pPlayer.GetTeamNumber() == TEAM_SURVIVOR ){

                    Vector ve = pPlayer.GetAbsOrigin();
                
                    // 距离
                    float jl = Globals.Distance(base.GetAbsOrigin(),ve);
                    Log.PrintToServerConsole(LOGTYPE_INFO,"----------Distance-----"+jl+"-------");

                    // 如果距离小于15米
                    if( Utils.FloatToInt(jl) < distance_delete*100){
                        needDelete = false;
                        break;
                    }

               }

            }
            if( needDelete ){
                base.SUB_StartFadeOut(1,false);
                Log.PrintToServerConsole(LOGTYPE_INFO,"-------------delete NPC--------------");
            }
        }
    }
}

//--------------------------------------------无限刷----------------------------------------

void MAXZOMBIE(){
    // 每隔5秒检测一次(放前面，防止下面代码执行失败就停掉了)
    Schedule::Task(1.0f,"MAXZOMBIE");
    // 如果玩家人数大于0了，就开始刷起来
    if( Utils.CollectPlayers().length() > 0 ){
        Log.PrintToServerConsole(LOGTYPE_INFO,"-------------------checking--------------");
        // 去找僵尸生成区
        string name = "trigger_zombie_spawns";
        CBaseEntity @pEnt = FindEntityByClassname( null, name );
        while( pEnt !is null)
        {
            // 如果 现在的NPC数量 < 我们设置的NPC常数数量
            int num = Utils.CollectSurvivors().length();
            if( num < NPCC ){
                
                Log.PrintToServerConsole(LOGTYPE_INFO,"--------"+num+"--------"+NPCC+"--------");

                // 玩家列表中随机拿取一个玩家的索引值
                int index = Math::RandomInt(1,Utils.CollectPlayers().length());
                //转化为实体对象
                CTerrorPlayer@ pPlayer = ToTerrorPlayer(index);
                
                if( pPlayer.GetTeamNumber() == TEAM_SURVIVOR ){

                    //Log.PrintToServerConsole(LOGTYPE_INFO,"--------getPlayer--------"+pPlayer.GetPlayerName()+"--------");

                    // 得到这个玩家的坐标
                    Vector ve = pPlayer.GetAbsOrigin();

                    // 然后去测量这个僵尸生成区与这个玩家的距离
                    float jl = Globals.Distance(pEnt.GetAbsOrigin(),ve);
                    //Log.PrintToServerConsole(LOGTYPE_INFO,"--------player/trigger--------"+jl+"--------");

                    // 如果距离小于10米
                    if( Utils.FloatToInt(jl) < distance_respawn*100 ){

                        // 在僵尸生成区开始生成僵尸
                        ThePresident.SpawnZombiesForceArea(20,pEnt.GetEntityName());
                    
                    }
                }

                @pEnt = FindEntityByClassname( pEnt, name );

            }else{

                Log.PrintToServerConsole(LOGTYPE_INFO,"----------OK---------");
                @pEnt = null;

            }
        }
    }
}